ENT.Type = "anim"
ENT.PrintName		= ""
ENT.Author			= ""
ENT.Contact			= ""
ENT.Purpose			= ""
ENT.Instructions	= ""

ENT.Spawnable			= false
ENT.AdminSpawnable		= false

ID_PREV_ENTITY = "eprv"
ID_NEXT_ENTITY = "enxt"
ID_ROOT_ENTITY = "erot"
ID_ENTITY_NAME = "enam"
ID_CAMERA_FRAME_NAME = "cfnm"
ID_PATH_DIRECTION = "epdi"
ID_PATH_DIRECTION_ENTITY_A = "epea"
ID_PATH_DIRECTION_ENTITY_B = "epeb"
ID_NODE_ID = "nid"
NAME_OFFSET = Vector(0,0,30)


function ENT:PrintError(details)
	print("********************")
	print("* ERROR")
	print("* Details: " .. details)
	print("* Please tell Gareth")
	return false
end

function ENT:PrintWarning(details)
	print("********************")
	print("* WARNING")
	print("* Details: " .. details)
	print("* Please tell Gareth")
	return false
end

function ENT:IsValid(ent)

	if(ent == nil or ent == NULL or !ent:IsValid()) then
		return false
	else
		return true
	end
end

//****************************************************
//* Appends this node onto the passed chain/linked list 
function ENT:InitalizeChain(prev)
	if SERVER then

		if self.BaseClass.IsValid(self,prev) then

			self:SetNWInt(ID_NODE_ID, (prev:GetNWInt(ID_NODE_ID) + 1))

			if self.BaseClass.IsValid(self, prev:GetNWEntity(ID_NEXT_ENTITY)) then
				self:PrintWarning("Overwriting links in chain")
			end

			if self.BaseClass.IsValid(self, self:GetNWEntity(ID_NEXT_ENTITY)) then
				self:PrintWarning("Disjoint chain detected")
			end

			self:SetNWEntity(ID_PREV_ENTITY, prev)
			prev:SetNWEntity(ID_NEXT_ENTITY, self)
		
		 //The previous node (from the tool gun) is invalid however this
		 //still could mean that a track exisits with the same name that 
		 //we should attach too
		else

			//If no other track exists, the id will be left as this
			self:SetNWInt(ID_NODE_ID, 1) 

			local nodeEnts = ents.FindByClass(self:GetClass())
			for _, node in pairs(nodeEnts) do
				if node and node:IsValid() then

					local nodeName = self.BaseClass.GetName(node)
					local selfName = self:GetNWString(ID_ENTITY_NAME)
					
					if nodeName == selfName and node != self then
						
						local lastNode = self.BaseClass.GetLastNode(node)
						lastNode:SetNWEntity(ID_NEXT_ENTITY, self)
						self:SetNWEntity(ID_PREV_ENTITY, lastNode)
						self:SetNWEntity(ID_NEXT_ENTITY, nil)
						self:SetNWInt(ID_NODE_ID, lastNode:GetNWInt(ID_NODE_ID) + 1)
						break

					end
				end
			end
		
		end
	end
end

//****************************************************
//* Sets the curve tangent
function ENT:SetCurveTangent(vec)
	if SERVER and vec != nil then
		self:SetNWVector(ID_PATH_DIRECTION, vec)
		local gripA = self:GetNWEntity(ID_PATH_DIRECTION_ENTITY_A)
		local gripB = self:GetNWEntity(ID_PATH_DIRECTION_ENTITY_B)

		gripA:SetPos(self:GetPos() + vec)
		gripB:SetPos(self:GetPos() - vec)
	end
end

//****************************************************
//* TODO: work out why this is nessisary!!
function GetRootNode(node)

	local rootNode = node
	if node and node:IsValid() then

		while true do
			local nextPrev = rootNode.BaseClass.GetPrevNode(rootNode)	
			if nextPrev and nextPrev:IsValid() then
				rootNode = nextPrev
			else
				break
			end
		end
	end

	return rootNode
end

//****************************************************
//* Accesses the root node of this track
function ENT:GetRootNode()

	local rootNode = self	

	while true do
		local nextPrev = self.BaseClass.GetPrevNode(rootNode)	
		if nextPrev and self.BaseClass.IsValid(nextPrev) then
			rootNode = nextPrev
		else
			break
		end
	end

	return rootNode
end

//****************************************************
//* Accesses the last node of this track
function ENT:GetLastNode()

	local rootNode = self	

	while true do
		local nextPrev = rootNode.BaseClass.GetNextNode(rootNode)	
		if self.BaseClass.IsValid(self, nextPrev) then
			rootNode = nextPrev
		else
			break
		end
	end
	return rootNode
end

//****************************************************
//* Accesses the root node of this track
function ENT:GetPathLength()

	local rootNode = self.BaseClass.GetRootNode(self)
	local count = 0

	while self.BaseClass.IsValid(self, rootNode) do
		rootNode = rootNode.BaseClass.GetNextNode(rootNode)	
		count = count + 1
	end

	return count
end

//****************************************************
//* Enables a name to be retrieved from this track. Only
//* the root node has data accesssed
function ENT:GetName()

	local rootNode = self.BaseClass.GetRootNode(self)

	if self == rootNode then
		return self:GetNWString(ID_ENTITY_NAME)
	else
		return rootNode.BaseClass.GetName(rootNode)
	end
end

//****************************************************
//* Enables a name to be assigned to this track. Only
//* the root node of this track is assigned data
function ENT:SetName(val)
	local rootNode = self:GetRootNode()

	if self == rootNode then
		self:SetNWString(ID_ENTITY_NAME, val)
	else
		rootNode:SetName(val)
	end
end

//****************************************************
//* Accesses the next node of this track
function ENT:GetNextNode()
	return self:GetNWEntity(ID_NEXT_ENTITY)
end

//****************************************************
//* Accesses the previous node of this track
function ENT:GetPrevNode()
	return self:GetNWEntity(ID_PREV_ENTITY)
end